﻿#include "File.h"
#include "Tracer.h"
#ifdef OS_CYGWIN
void TestOssAudio()
{
    TRACE_ERR("Not support Audio.\n");
}
#else
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <linux/soundcard.h>

#define WAV_FMT_PCM 1
static char wavHeader[]={
'R','I','F','F',            /* 00H */
0xfc,0xff,0xff,0xff,        /* 04H,文件长度 */
'W','A','V','E',            /* 08H */
'f','m','t',' ',            /* 0CH */
16,0,0,0,                   /* 10H,过渡字节(不定) */
WAV_FMT_PCM,WAV_FMT_PCM>>8, /* 14H,格式类别 */
2,0,                        /* 16H,声道数 */
0,0,0,0,                    /* 18H,采样频率:1F40=8000 */
0,0,0,0,                    /* 1CH,位速(每秒所需字节数)3E80=16000 */
0,0,                        /* 20H,一个采样多声道数据块大小 */
16,0,                       /* 22H,一个采样占的位数 */
'd','a','t','a',            /* 24H,数据标记符 */
0xd8,0xff,0xff,0xff         /* 28H,语音数据的长度,比文件长度小36 */
};

void store2(char *pos,short value)
{
    memcpy(pos,&value,2);
}

void store4(char *pos,int value)
{
    memcpy(pos,&value,4);
}

void add_header(int size,short chans,int rate)
{
    store4(wavHeader+0x04,size+0x24);
    store2(wavHeader+0x16,chans);
    store4(wavHeader+0x18,rate);
    store4(wavHeader+0x1C,rate*chans);  //rate*chans*2
    store2(wavHeader+0x20,chans);      //chans*AUDIO_BITS/8 or chan*2
    store4(wavHeader+0x28,size);
}

#define AUDIO_DEV       "/dev/dsp"
#define AUDIO_BITS      8
#define AUDIO_CHANS     2
#define AUDIO_RATE     (8192)

int wav_record(int seconds)
{
    int arg;
    int ret;
    int fd = open(AUDIO_DEV,O_RDONLY);
    if (fd < 0)
    {
        TRACE_ERR("open dev error:%s\n",AUDIO_DEV);
        return 0;
    }

    ioctl(fd,SOUND_PCM_READ_BITS,&arg);
    TRACE_DBG("bits=%d\n",arg);
    ioctl(fd,SOUND_PCM_READ_CHANNELS,&arg);
    TRACE_DBG("channels=%d\n",arg);
    ioctl(fd,SOUND_PCM_READ_RATE,&arg);
    TRACE_DBG("rate=%d\n",arg);

    #if 1
    arg = AUDIO_BITS;
    ret = ioctl(fd,SOUND_PCM_WRITE_BITS,&arg);
    if (ret<0)
    {
        TRACE_ERR("SOUND_PCM_WRITE_BITS error!\n");
        return 0;
    }

    arg = AUDIO_CHANS;
    ret = ioctl(fd,SOUND_PCM_WRITE_CHANNELS,&arg);
    if (ret<0)
    {
        TRACE_ERR("SOUND_PCM_WRITE_CHANNELS error!\n");
        return 0;
    }

    arg = AUDIO_RATE;
    ret = ioctl(fd,SOUND_PCM_WRITE_RATE,&arg);
    if (ret<0)
    {
        TRACE_ERR("SOUND_PCM_WRITE_RATE error!\n");
        return 0;
    }
    #endif
    
    File file;
    file.open("rec.raw",IO_MODE_RDWR_ORNEW);
    int i=0;
    while(i<40)
    {
        char buf[1024]={0};
        int len = read(fd,buf,1024);
        if (len>0)
        {
            file.writeData(buf, len);
            TRACE_DBG("read audio data:%d\n",len);
        }
        i++;
    }
    
    int size = file.getSize();
    file.close();
    close(fd);
    return size;
}

void TestOssAudio()
{
    int size = wav_record(10);
    File file;
    add_header(size, 1, 8192);
    file.open("rec.wav", IO_MODE_REWR_ORNEW);
    file.writeData(wavHeader, sizeof(wavHeader));

    File rawFile;
    int len;
    rawFile.open("rec.raw",IO_MODE_RD_ONLY);
    len = rawFile.getSize();
    if (len<=0)
    {
        TRACE_ERR("Can't read file: rec.raw.\n");
        return;
    }
    while(len>0)
    {
        char tmp[256]={0};
        int rLen = rawFile.readData(tmp, 256);
        file.writeData(tmp, rLen);
        len = len - rLen;
    }
    rawFile.close();
    file.close();
}
#endif
